#pragma once

#include <stlcompat/span.h>

#include <cstddef>
#include <iterator>
#include <limits>
#include <string_view>
#include <type_traits>
#include <utility>

/**
 * @file serializer/traits.h
 * @brief 序列化库中所有类型特征（type-traits）与“概念”检测的集中定义。
 * @details
 *  本文件承担三大职责：
 *  1. 编译期检测编译器/标准库能力（std::span、字节序等）。
 *  2. 对“Writer / Reader / Options / Context / Error”五大扩展点进行
 *     精细的“方法存在性”检测，为后续 SFINAE 与 if constexpr 分发提供基石。
 *  3. 在 C++17 无 Concepts 的环境下，用变量模板模拟出“概念”语义，
 *     保证核心代码的可读性与可维护性。
 *
 *  设计要点：
 *  - 全部检测器均放在 `serializer::detail` 内，对外不可见，避免污染 ADL。
 *  - 检测器采用“has_xxx”命名，返回 `std::true_type / false_type`，
 *     上层再用 `constexpr bool xxx = has_xxx<T>::value` 提供用户友好接口。
 *  - 所有“概念”变量模板均使用 `constexpr bool`，保证在 if constexpr、
 *     `std::enable_if_t`、`requires`（将来迁移到 C++20）等场景下零成本使用。
 */

// ============================================================================
//  编译期能力检测
// ============================================================================

/**
 * @def SERIALIZER_NATIVE_ENDIAN_LITTLE / SERIALIZER_NATIVE_ENDIAN_BIG
 * @brief 编译期字节序检测。
 * @details
 *  优先使用编译器内置宏 `__BYTE_ORDER__` 进行精确判断；
 *  对 Windows、常见嵌入式宏做特例化；若全部失败则回退到 little-endian，
 *  保证在任何平台都能通过编译。序列化/反序列化整数、浮点数时
 *  依赖该宏决定是否需要手工字节交换。
 */
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define SERIALIZER_NATIVE_ENDIAN_LITTLE 1
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define SERIALIZER_NATIVE_ENDIAN_BIG 1
#elif defined(_WIN32) || defined(_WIN64)
#define SERIALIZER_NATIVE_ENDIAN_LITTLE 1
#elif defined(__LITTLE_ENDIAN__)
#define SERIALIZER_NATIVE_ENDIAN_LITTLE 1
#elif defined(__BIG_ENDIAN__)
#define SERIALIZER_NATIVE_ENDIAN_BIG 1
#else
#define SERIALIZER_NATIVE_ENDIAN_LITTLE 1
#endif

namespace serializer
{
/**
 * @brief 内部实现细节命名空间，对外不可见。
 */
namespace detail
{

/**
 * @brief C++17 的 std::void_t 等价物。
 * @details
 *  用于检测表达式是否合法（SFINAE）。在 C++20 可直接使用 `std::void_t`，
 *  但为保证 C++17 兼容性，这里手工定义。
 */
template <typename...>
using void_t = void;

// ============================================================================
//  Writer 能力检测
// ============================================================================

/**
 * @brief 检测类型 `W` 是否具有 `write_bytes(const std::byte*, size_t)` 方法。
 * @details
 *  这是“基本 Writer”最核心的能力：把一段原始字节写入底层介质。
 *  返回 `std::true_type / false_type`，供上层变量模板 `basic_writer<W>` 使用。
 */
template <typename W, typename = void>
struct has_write_bytes_ptr : std::false_type
{
};

template <typename W>
struct has_write_bytes_ptr<
    W,
    void_t<decltype(std::declval<W &>().write_bytes(static_cast<const std::byte *>(nullptr),
                                                    std::declval<std::size_t>()))>> : std::true_type
{
};

/**
 * @brief 检测类型 `W` 是否具有 `position()` 方法，且返回值可转换为 `size_t`。
 * @details
 *  用于在序列化过程中记录当前写入位置，支持“先占位、后回填”等高级模式。
 */
template <typename W, typename = void>
struct has_position : std::false_type
{
};

template <typename W>
struct has_position<W, void_t<decltype(std::declval<W &>().position())>> : std::true_type
{
};

/**
 * @brief 检测类型 `W` 是否具有 `bytes_written()` 方法。
 * @details
 *  用于统计已经写入的字节数，与 `position()` 区别是：
 *  `position()` 通常返回逻辑偏移，`bytes_written()` 返回物理累计值。
 */
template <typename W, typename = void>
struct has_bytes_written : std::false_type
{
};

template <typename W>
struct has_bytes_written<W, void_t<decltype(std::declval<const W &>().bytes_written())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `W` 是否具有 `can_write(size_t) -> bool` 方法。
 * @details
 *  在写入前进行容量预检，避免中途失败导致已写入数据处于不一致状态。
 */
template <typename W, typename = void>
struct has_can_write : std::false_type
{
};

template <typename W>
struct has_can_write<
    W,
    void_t<decltype(std::declval<const W &>().can_write(std::declval<std::size_t>()))>>
    : std::true_type
{
};

// ============================================================================
//  Reader 能力检测
// ============================================================================

/**
 * @brief 检测类型 `R` 是否具有 `read_bytes(std::byte*, size_t)` 方法。
 * @details
 *  与 `has_write_bytes_ptr` 对应，是“基本 Reader”的核心能力。
 */
template <typename R, typename = void>
struct has_read_bytes_ptr : std::false_type
{
};

template <typename R>
struct has_read_bytes_ptr<R,
                          void_t<decltype(std::declval<R &>().read_bytes(
                              static_cast<std::byte *>(nullptr), std::declval<std::size_t>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `R` 是否具有 `has_data() -> bool` 方法。
 * @details
 *  用于在流式解析时快速判断“是否还有数据”，
 *  避免每次读取都触发异常或 EOF 标志。
 */
template <typename R, typename = void>
struct has_has_data : std::false_type
{
};

template <typename R>
struct has_has_data<R, void_t<decltype(std::declval<const R &>().has_data())>> : std::true_type
{
};

/**
 * @brief 检测类型 `R` 是否具有 `remaining_bytes() -> size_t` 方法。
 * @details
 *  用于在反序列化容器前预分配内存，避免多次扩容。
 */
template <typename R, typename = void>
struct has_remaining_bytes : std::false_type
{
};

template <typename R>
struct has_remaining_bytes<R, void_t<decltype(std::declval<const R &>().remaining_bytes())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `R` 是否具有 `can_read(size_t) -> bool` 方法。
 * @details
 *  与 `can_write` 对称，用于在读取前做容量预检。
 */
template <typename R, typename = void>
struct has_can_read : std::false_type
{
};

template <typename R>
struct has_can_read<
    R,
    void_t<decltype(std::declval<const R &>().can_read(std::declval<std::size_t>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `R` 是否具有 `position()` 方法。
 * @details
 *  用于在反序列化过程中记录当前读取位置，支持“跳转、回填”等高级模式。
 */
template <typename R, typename = void>
struct has_reader_position : std::false_type
{
};

template <typename R>
struct has_reader_position<R, void_t<decltype(std::declval<const R &>().position())>>
    : std::true_type
{
};

// ============================================================================
//  Options 能力检测
// ============================================================================

/**
 * @brief 检测类型 `O` 是否同时具有
 *  `get_byte_order() / max_container_size() / max_string_length() / max_recursion_depth()`
 *  四个方法。
 * @details
 *  这是“基本序列化选项”的最小能力集，用于控制字节序、容器上限、递归深度等
 *  与安全性息息相关的参数。
 */
template <typename O, typename = void>
struct has_options_basic : std::false_type
{
};

template <typename O>
struct has_options_basic<O,
                         void_t<decltype(std::declval<const O &>().get_byte_order()),
                                decltype(std::declval<const O &>().max_container_size()),
                                decltype(std::declval<const O &>().max_string_length()),
                                decltype(std::declval<const O &>().max_recursion_depth())>>
    : std::true_type
{
};

} // namespace detail

// ============================================================================
//  扩展 Writer / Reader / Options 能力检测
// ============================================================================

namespace detail
{

/**
 * @brief 检测类型 `W` 是否具有 `write_string_view(std::string_view)` 方法。
 * @details
 *  用于对字符串做零拷贝优化，避免先转成 `std::string` 再写入。
 */
template <typename W, typename = void>
struct has_write_string_view : std::false_type
{
};

template <typename W>
struct has_write_string_view<
    W,
    void_t<decltype(std::declval<W &>().write_string_view(std::declval<std::string_view>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `W` 是否具有 `write_bytes(kp::span<const std::byte>)` 方法。
 * @details
 *  与 `write_bytes(const std::byte*, size_t)` 相比，使用 `span` 可携带长度信息，
 *  减少参数个数，降低出错概率。
 */
template <typename W, typename = void>
struct has_write_bytes_span : std::false_type
{
};

template <typename W>
struct has_write_bytes_span<
    W,
    void_t<decltype(std::declval<W &>().write_bytes(std::declval<kp::span<const std::byte>>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `W` 是否具有 `seek(size_t)` 方法。
 * @details
 *  用于支持“可定位 Writer”，在序列化过程中可回跳、回填。
 */
template <typename W, typename = void>
struct has_writer_seek : std::false_type
{
};

template <typename W>
struct has_writer_seek<W, void_t<decltype(std::declval<W &>().seek(std::declval<std::size_t>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `W` 是否具有 `capacity() -> size_t` 方法。
 * @details
 *  用于在写入前做容量预检，避免中途扩容导致性能回退。
 */
template <typename W, typename = void>
struct has_writer_capacity : std::false_type
{
};

template <typename W>
struct has_writer_capacity<W, void_t<decltype(std::declval<W &>().capacity())>> : std::true_type
{
};

/**
 * @brief 检测类型 `R` 是否具有 `read_bytes(kp::span<std::byte>)` 方法。
 * @details
 *  与 `write_bytes(span)` 对称，支持零拷贝读取到 `span`。
 */
template <typename R, typename = void>
struct has_read_bytes_span : std::false_type
{
};

template <typename R>
struct has_read_bytes_span<
    R,
    void_t<decltype(std::declval<R &>().read_bytes(std::declval<kp::span<std::byte>>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `R` 是否具有 `read_string(size_t) -> std::string` 方法。
 * @details
 *  用于对字符串做特殊处理，避免先读长度再手动构造 `std::string`。
 */
template <typename R, typename = void>
struct has_read_string : std::false_type
{
};

template <typename R>
struct has_read_string<
    R,
    void_t<decltype(std::declval<R &>().read_string(std::declval<std::size_t>()))>> : std::true_type
{
};

/**
 * @brief 检测类型 `R` 是否具有 `seek(size_t)` 方法。
 * @details
 *  与 `has_writer_seek` 对称，支持“可定位 Reader”。
 */
template <typename R, typename = void>
struct has_reader_seek : std::false_type
{
};

template <typename R>
struct has_reader_seek<R, void_t<decltype(std::declval<R &>().seek(std::declval<std::size_t>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `R` 是否具有 `size() -> size_t` 方法。
 * @details
 *  用于在反序列化前预分配容器，避免多次扩容。
 */
template <typename R, typename = void>
struct has_reader_size : std::false_type
{
};

template <typename R>
struct has_reader_size<R, void_t<decltype(std::declval<R &>().size())>> : std::true_type
{
};

// ============================================================================
//  扩展 Options 能力检测
// ============================================================================

/**
 * @brief 检测类型 `O` 是否具有 `enable_compression() -> bool` 方法。
 * @details
 *  用于控制是否启用压缩，通常在 `extended_serialization_options` 中统一检查。
 */
template <typename O, typename = void>
struct has_enable_compression : std::false_type
{
};

template <typename O>
struct has_enable_compression<O, void_t<decltype(std::declval<const O &>().enable_compression())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `O` 是否具有 `enable_checksum() -> bool` 方法。
 * @details
 *  用于控制是否启用校验和，保证数据完整性。
 */
template <typename O, typename = void>
struct has_enable_checksum : std::false_type
{
};

template <typename O>
struct has_enable_checksum<O, void_t<decltype(std::declval<const O &>().enable_checksum())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `O` 是否具有 `version() -> uint32_t` 方法。
 * @details
 *  用于版本控制，支持向后兼容。
 */
template <typename O, typename = void>
struct has_version_u32 : std::false_type
{
};

template <typename O>
struct has_version_u32<O, void_t<decltype(std::declval<const O &>().version())>> : std::true_type
{
};

/**
 * @brief 检测类型 `O` 是否具有 `enable_debug() -> bool` 方法。
 * @details
 *  用于控制是否启用调试模式，通常会在序列化过程中插入额外调试信息。
 */
template <typename O, typename = void>
struct has_enable_debug : std::false_type
{
};

template <typename O>
struct has_enable_debug<O, void_t<decltype(std::declval<const O &>().enable_debug())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `O` 是否具有 `enable_varint_lengths() -> bool` 方法。
 * @details
 *  用于控制是否使用 varint 编码长度，可减少序列化后体积。
 */
template <typename O, typename = void>
struct has_enable_varint_lengths : std::false_type
{
};

template <typename O>
struct has_enable_varint_lengths<
    O,
    void_t<decltype(std::declval<const O &>().enable_varint_lengths())>> : std::true_type
{
};

/**
 * @brief 检测类型 `O` 是否具有 `prefer_decimal_for_long_double() -> bool` 方法。
 * @details
 *  用于控制 `long double` 是否使用十进制文本格式，避免二进制精度丢失。
 */
template <typename O, typename = void>
struct has_prefer_decimal_for_long_double : std::false_type
{
};

template <typename O>
struct has_prefer_decimal_for_long_double<
    O,
    void_t<decltype(std::declval<const O &>().prefer_decimal_for_long_double())>> : std::true_type
{
};

// ============================================================================
//  Context 能力检测
// ============================================================================

/**
 * @brief 检测类型 `C` 是否具有 `current_depth() -> size_t` 方法。
 * @details
 *  用于在序列化/反序列化嵌套结构时记录当前递归深度，防止栈溢出。
 */
template <typename C, typename = void>
struct has_current_depth : std::false_type
{
};

template <typename C>
struct has_current_depth<C, void_t<decltype(std::declval<C &>().current_depth())>> : std::true_type
{
};

/**
 * @brief 检测类型 `C` 是否具有 `increment_depth()` 方法。
 * @details
 *  在进入嵌套结构时调用，用于深度计数器加一。
 */
template <typename C, typename = void>
struct has_increment_depth : std::false_type
{
};

template <typename C>
struct has_increment_depth<C, void_t<decltype(std::declval<C &>().increment_depth())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `C` 是否具有 `decrement_depth()` 方法。
 * @details
 *  在离开嵌套结构时调用，用于深度计数器减一。
 */
template <typename C, typename = void>
struct has_decrement_depth : std::false_type
{
};

template <typename C>
struct has_decrement_depth<C, void_t<decltype(std::declval<C &>().decrement_depth())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `C` 是否具有 `check_depth_limit() -> bool` 方法。
 * @details
 *  用于在每次 `increment_depth` 后检查是否超过上限，防止恶意数据导致无限递归。
 */
template <typename C, typename = void>
struct has_check_depth_limit : std::false_type
{
};

template <typename C>
struct has_check_depth_limit<C, void_t<decltype(std::declval<C &>().check_depth_limit())>>
    : std::true_type
{
};

// ============================================================================
//  扩展 Context 能力检测
// ============================================================================

/**
 * @brief 检测类型 `C` 是否具有 `has_circular_reference(const void*) -> bool` 方法。
 * @details
 *  用于在序列化对象图时检测循环引用，避免无限递归。
 */
template <typename C, typename = void>
struct has_has_circular_reference : std::false_type
{
};

template <typename C>
struct has_has_circular_reference<C,
                                  void_t<decltype(std::declval<C &>().has_circular_reference(
                                      static_cast<const void *>(nullptr)))>> : std::true_type
{
};

/**
 * @brief 检测类型 `C` 是否具有 `add_reference(const void*)` 方法。
 * @details
 *  在序列化对象地址时调用，用于记录“已序列化”指针，支持后续循环引用检测。
 */
template <typename C, typename = void>
struct has_add_reference : std::false_type
{
};

template <typename C>
struct has_add_reference<
    C,
    void_t<decltype(std::declval<C &>().add_reference(static_cast<const void *>(nullptr)))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `C` 是否具有 `remove_reference(const void*)` 方法。
 * @details
 *  在离开对象作用域时调用，用于清理“已序列化”记录。
 */
template <typename C, typename = void>
struct has_remove_reference : std::false_type
{
};

template <typename C>
struct has_remove_reference<
    C,
    void_t<decltype(std::declval<C &>().remove_reference(static_cast<const void *>(nullptr)))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `C` 是否具有 `bytes_processed() -> size_t` 方法。
 * @details
 *  用于统计已经处理的字节数，通常用于进度报告或限速。
 */
template <typename C, typename = void>
struct has_bytes_processed : std::false_type
{
};

template <typename C>
struct has_bytes_processed<C, void_t<decltype(std::declval<C &>().bytes_processed())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `C` 是否具有 `objects_processed() -> size_t` 方法。
 * @details
 *  用于统计已经处理的对象个数，通常用于调试或性能剖析。
 */
template <typename C, typename = void>
struct has_objects_processed : std::false_type
{
};

template <typename C>
struct has_objects_processed<C, void_t<decltype(std::declval<C &>().objects_processed())>>
    : std::true_type
{
};

// ============================================================================
//  Error 能力检测
// ============================================================================

/**
 * @brief 检测类型 `E` 是否具有 `message() -> std::string` 方法。
 * @details
 *  这是“基本错误”最小能力，用于向用户返回可读错误信息。
 */
template <typename E, typename = void>
struct has_error_message : std::false_type
{
};

template <typename E>
struct has_error_message<E, void_t<decltype(std::declval<const E &>().message())>> : std::true_type
{
};

/**
 * @brief 检测类型 `E` 是否具有 `code() -> int` 方法。
 * @details
 *  用于返回错误码，方便程序做分类处理（重试、降级、上报）。
 */
template <typename E, typename = void>
struct has_error_code : std::false_type
{
};

template <typename E>
struct has_error_code<E, void_t<decltype(std::declval<const E &>().code())>> : std::true_type
{
};

/**
 * @brief 检测类型 `E` 是否具有 `position() -> size_t` 方法。
 * @details
 *  用于返回错误发生时的字节偏移，方便定位问题数据。
 */
template <typename E, typename = void>
struct has_error_position : std::false_type
{
};

template <typename E>
struct has_error_position<E, void_t<decltype(std::declval<const E &>().position())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `E` 是否具有 `type_name() -> std::string` 方法。
 * @details
 *  用于返回出错时的具体类型名，方便调试与日志。
 */
template <typename E, typename = void>
struct has_error_type_name : std::false_type
{
};

template <typename E>
struct has_error_type_name<E, void_t<decltype(std::declval<const E &>().type_name())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `E` 是否具有 `stack_trace() -> std::string` 方法。
 * @details
 *  用于返回出错时的调用栈，方便定位问题。
 */
template <typename E, typename = void>
struct has_error_stack_trace : std::false_type
{
};

template <typename E>
struct has_error_stack_trace<E, void_t<decltype(std::declval<const E &>().stack_trace())>>
    : std::true_type
{
};

/**
 * @brief 检测类型 `E` 是否具有 `context() -> std::string` 方法。
 * @details
 *  用于返回出错时的上下文信息（例如当前字段名、容器索引等），
 *  方便用户快速定位问题。
 */
template <typename E, typename = void>
struct has_error_context : std::false_type
{
};

template <typename E>
struct has_error_context<E, void_t<decltype(std::declval<const E &>().context())>> : std::true_type
{
};

} // namespace detail

// ============================================================================
//  基础类型“概念”变量模板
// ============================================================================

/**
 * @brief 判断 `T` 是否为算术类型（整数、浮点、布尔）。
 * @details
 *  直接复用 `std::is_arithmetic`，保证与标准库定义一致。
 */
template <typename T>
constexpr bool arithmetic_type = std::is_arithmetic<T>::value;

/**
 * @brief 判断 `T` 是否为 IEEE-754 单精度或双精度浮点。
 * @details
 *  用于在序列化时选择“二进制直接写”还是“文本格式”，
 *  保证跨平台比特一致性。
 */
template <typename T>
constexpr bool
    ieee754_float = std::is_floating_point<T>::value && std::numeric_limits<T>::is_iec559 &&
                    (sizeof(T) == 4 || sizeof(T) == 8);

/**
 * @brief 判断 `T` 是否为“可移植算术类型”。
 * @details
 *  目前定义为：所有整数 + IEEE-754 单/双精度。
 *  这些类型在主流平台（LP64/LLP64/ILP32）上拥有相同布局，
 *  可直接 memcpy 序列化。
 */
template <typename T>
constexpr bool portable_arithmetic_type = std::is_integral<T>::value || ieee754_float<T>;

/**
 * @brief 判断 `T` 是否为“字节类型”。
 * @details
 *  包括 `std::byte / char / unsigned char / signed char`。
 *  这些类型在序列化时通常不需要做任何编码转换，
 *  可直接写入。
 */
template <typename T>
constexpr bool byte_type =
    std::is_same<T, std::byte>::value || std::is_same<T, char>::value ||
    std::is_same<T, unsigned char>::value || std::is_same<T, signed char>::value;

// ============================================================================
//  Writer “概念”变量模板
// ============================================================================

/**
 * @brief 判断 `W` 是否满足“基本 Writer”概念。
 * @details
 *  要求同时具有 `write_bytes(const std::byte*, size_t)` 与 `position()`。
 *  这是“能写”的最小能力集。
 */
template <typename W>
constexpr bool basic_writer =
    detail::has_write_bytes_ptr<W>::value && detail::has_position<W>::value;

/**
 * @brief 判断 `W` 是否满足“扩展 Writer”概念。
 * @details
 *  在 `basic_writer` 基础上，额外要求
 *  `write_bytes(span)`、`write_string_view`、`bytes_written`、`can_write`。
 *  上层算法在检测到 `extended_writer` 时可启用更多优化路径。
 */
template <typename W>
constexpr bool extended_writer =
    basic_writer<W> && detail::has_write_bytes_span<W>::value && detail::has_write_string_view<
        W>::value && detail::has_bytes_written<W>::value && detail::has_can_write<W>::value;

/**
 * @brief 判断 `W` 是否满足“可定位 Writer”概念。
 * @details
 *  在 `basic_writer` 基础上，额外要求 `seek(size_t)` 与 `capacity()`。
 *  支持“先占位、后回填”模式，例如跳过长度字段、后期修正。
 */
template <typename W>
constexpr bool seekable_writer =
    basic_writer<W> && detail::has_writer_seek<W>::value && detail::has_writer_capacity<W>::value;

/**
 * @brief 对“Writer”概念的统一别名。
 * @details
 *  目前直接等同于 `basic_writer`，未来若引入更轻量或更重量分级，
 *  可在此统一调整，保持上层代码零改动。
 */
template <typename W>
constexpr bool writer = basic_writer<W>;

// ============================================================================
//  Reader “概念”变量模板
// ============================================================================

/**
 * @brief 判断 `R` 是否满足“基本 Reader”概念。
 * @details
 *  要求同时具有 `read_bytes(std::byte*, size_t)`、`position()`、`has_data()`。
 *  这是“能读”的最小能力集。
 */
template <typename R>
constexpr bool basic_reader = detail::has_read_bytes_ptr<R>::value &&
    detail::has_reader_position<R>::value && detail::has_has_data<R>::value;

/**
 * @brief 判断 `R` 是否满足“扩展 Reader”概念。
 * @details
 *  在 `basic_reader` 基础上，额外要求
 *  `read_bytes(span)`、`read_string(size_t)`、`remaining_bytes`、`can_read`。
 *  上层算法在检测到 `extended_reader` 时可启用更多优化路径。
 */
template <typename R>
constexpr bool extended_reader =
    basic_reader<R> && detail::has_read_bytes_span<R>::value && detail::has_read_string<R>::value &&
        detail::has_remaining_bytes<R>::value && detail::has_can_read<R>::value;

/**
 * @brief 判断 `R` 是否满足“可定位 Reader”概念。
 * @details
 *  在 `basic_reader` 基础上，额外要求 `seek(size_t)` 与 `size()`。
 *  支持“跳转、重读”模式，例如反序列化容器时先读长度、再读元素。
 */
template <typename R>
constexpr bool seekable_reader =
    basic_reader<R> && detail::has_reader_seek<R>::value && detail::has_reader_size<R>::value;

/**
 * @brief 对“Reader”概念的统一别名。
 * @details
 *  目前直接等同于 `basic_reader`，未来若引入更轻量或更重量分级，
 *  可在此统一调整，保持上层代码零改动。
 */
template <typename R>
constexpr bool reader = basic_reader<R>;

// ============================================================================
//  Options / Context / Error “概念”变量模板
// ============================================================================

/**
 * @brief 用户可见的“概念”变量模板：判断类型 O 是否满足“基本序列化选项”约束。
 */
template <typename O>
constexpr bool serialization_options = serializer::detail::has_options_basic<O>::value;

/**
 * @brief 扩展序列化选项：检测压缩、校验、版本、调试能力。
 */
template <typename O>
constexpr bool extended_serialization_options = serializer::detail::has_enable_compression<
    O>::value && serializer::detail::has_enable_checksum<O>::value &&
    serializer::detail::has_version_u32<O>::value && serializer::detail::has_enable_debug<O>::value;

/**
 * @brief 基础序列化上下文概念：深度管理与限幅检查。
 */
template <typename C>
constexpr bool serialization_context = serializer::detail::has_current_depth<C>::value &&
    serializer::detail::has_increment_depth<C>::value && serializer::detail::has_decrement_depth<
        C>::value && serializer::detail::has_check_depth_limit<C>::value;

/**
 * @brief 扩展序列化上下文概念：循环引用与处理计数。
 */
template <typename C>
constexpr bool extended_serialization_context =
    serialization_context<C> && serializer::detail::has_has_circular_reference<C>::value &&
        serializer::detail::has_add_reference<C>::value && serializer::detail::has_remove_reference<
            C>::value && serializer::detail::has_bytes_processed<C>::value &&
            serializer::detail::has_objects_processed<C>::value;

/**
 * @brief 基础序列化错误概念：消息、错误码、位置。
 */
template <typename E>
constexpr bool serialization_error =
    serializer::detail::has_error_message<E>::value && serializer::detail::has_error_code<
        E>::value && serializer::detail::has_error_position<E>::value;

/**
 * @brief 扩展序列化错误概念：类型名、栈追踪、上下文。
 */
template <typename E>
constexpr bool extended_serialization_error =
    serialization_error<E> && serializer::detail::has_error_type_name<E>::value &&
        serializer::detail::has_error_stack_trace<E>::value &&
            serializer::detail::has_error_context<E>::value;

/// @private
/// @brief 容器特征实现细节，对外不可见。
namespace detail
{
/**
 * @brief 检测类型 T 是否拥有嵌套类型 `value_type`。
 * @details
 *  几乎所有 STL 容器都提供 `value_type`，它是容器元素类型的统一入口。
 *  后续 `HasPushBack`、`HasInsert` 等 traits 均依赖它做 `decltype` 推导。
 */
template <typename T, typename = void>
struct has_value_type : std::false_type
{
};
template <typename T>
struct has_value_type<T, void_t<typename T::value_type>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有嵌套类型 `key_type`。
 * @details
 *  关联容器（map/unordered_map/set/unordered_set）必备特征，
 *  用于区分“键值对”与“单纯值”容器。
 */
template <typename T, typename = void>
struct has_key_type : std::false_type
{
};
template <typename T>
struct has_key_type<T, void_t<typename T::key_type>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有嵌套类型 `mapped_type`。
 * @details
 *  只有 *map 系列容器才同时拥有 `key_type` 与 `mapped_type`，
 *  借此可精确区分 `map` 与 `set`。
 */
template <typename T, typename = void>
struct has_mapped_type : std::false_type
{
};
template <typename T>
struct has_mapped_type<T, void_t<typename T::mapped_type>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有嵌套类型 `container_type`。
 * @details
 *  容器适配器（std::stack、std::queue、std::priority_queue）的共性特征，
 *  通过它可以把适配器“还原”到底层线性容器，从而复用批量序列化路径。
 */
template <typename T, typename = void>
struct has_container_type : std::false_type
{
};
template <typename T>
struct has_container_type<T, void_t<typename T::container_type>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `size()` 成员函数。
 * @details
 *  所有 STL 容器的“容量”统一入口，用于在序列化前预分配内存或写入元素个数。
 */
template <typename T, typename = void>
struct has_size_method : std::false_type
{
};
template <typename T>
struct has_size_method<T, void_t<decltype(std::declval<const T &>().size())>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `empty()` 成员函数。
 * @details
 *  与 `size()` 配对，用于快速判断容器是否为空，常见于边界检查与优化路径。
 */
template <typename T, typename = void>
struct has_empty_method : std::false_type
{
};
template <typename T>
struct has_empty_method<T, void_t<decltype(std::declval<const T &>().empty())>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `begin()` 成员函数。
 * @details
 *  范围 for 循环与 STL 算法的基石；用于在反序列化时逐元素插入。
 */
template <typename T, typename = void>
struct has_begin_method : std::false_type
{
};
template <typename T>
struct has_begin_method<T, void_t<decltype(std::declval<T &>().begin())>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `end()` 成员函数。
 * @details
 *  与 `begin()` 配对，构成半开区间 [begin, end)，是范围迭代的必要条件。
 */
template <typename T, typename = void>
struct has_end_method : std::false_type
{
};
template <typename T>
struct has_end_method<T, void_t<decltype(std::declval<T &>().end())>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `data()` 成员函数。
 * @details
 *  连续内存容器（vector/string/array/span）专有接口，返回 `T::value_type*`。
 *  借助它可实现“零拷贝”批量序列化：直接 `write_bytes(data(), size()*sizeof(value_type))`。
 */
template <typename T, typename = void>
struct has_data_method : std::false_type
{
};
template <typename T>
struct has_data_method<T, void_t<decltype(std::declval<T &>().data())>> : std::true_type
{
};

/**
 * @brief 校验 `data()` 返回值是否为指向 `value_type` 的裸指针。
 * @details
 *  防止某些类型虽然提供了 `data()`，但返回 `void*` 或自定义句柄，
 *  导致“连续内存”假设失效。只有返回 `T::value_type*` 才视为真正的连续容器。
 */
template <typename T, typename = void>
struct data_points_to_value_type_impl : std::false_type
{
};
template <typename T>
struct data_points_to_value_type_impl<
    T,
    void_t<typename T::value_type, decltype(std::declval<T &>().data())>>
{
    using P = decltype(std::declval<T &>().data());
    static constexpr bool value =
        std::is_pointer<P>::value &&
        std::is_same<std::remove_cv_t<std::remove_pointer_t<P>>, typename T::value_type>::value;
};

/// @brief 容器适配器 API 检测子模块
/// @details
///  适配器（stack/queue/priority_queue）没有迭代器，只能通过 `top/front/back/push`
///  进行元素访问与写入，因此需要独立一套检测器。
/// @{

/**
 * @brief 检测类型 T 是否拥有 `top()` 成员函数。
 * @details
 *  std::stack 与 std::priority_queue 的专属接口，用于访问“栈顶”或“最高优先级”元素。
 */
template <typename T, typename = void>
struct has_top_method : std::false_type
{
};
template <typename T>
struct has_top_method<T, void_t<decltype(std::declval<T &>().top())>> : std::true_type
{
};

/**
 * @brief 检测 `top()` 返回类型是否为 const 引用（priority_queue 的特征）。
 * @details
 *  仅在存在 `top()` 的情况下参与推导；否则回退为 `false_type`，避免硬错误。
 */
template <typename T, typename = void>
struct top_returns_const : std::false_type
{
};
template <typename T>
struct top_returns_const<T, void_t<decltype(std::declval<T &>().top())>>
{
    using top_ref_t = decltype(std::declval<T &>().top());
    static constexpr bool value = std::is_const<std::remove_reference_t<top_ref_t>>::value;
};

/**
 * @brief 检测类型 T 是否拥有 `front()` 成员函数。
 * @details
 *  std::queue 的专属接口，用于访问“队首”元素。
 */
template <typename T, typename = void>
struct has_front_method : std::false_type
{
};
template <typename T>
struct has_front_method<T, void_t<decltype(std::declval<T &>().front())>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `back()` 成员函数。
 * @details
 *  std::queue 的专属接口，用于访问“队尾”元素。
 */
template <typename T, typename = void>
struct has_back_method : std::false_type
{
};
template <typename T>
struct has_back_method<T, void_t<decltype(std::declval<T &>().back())>> : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `push(const value_type&)` 成员函数。
 * @details
 *  所有容器适配器统一使用 `push` 进行元素写入（与序列化后的还原阶段对应）。
 */
template <typename T, typename = void>
struct has_push_method : std::false_type
{
};
template <typename T>
struct has_push_method<
    T,
    void_t<typename T::value_type,
           decltype(std::declval<T &>().push(std::declval<typename T::value_type>()))>>
    : std::true_type
{
};
/// @}
} // namespace detail

// 公开的容器类型特征（struct 版本，供 ::value 使用）
template <typename T>
struct HasKeyType : std::bool_constant<detail::has_key_type<T>::value>
{
};

template <typename T>
struct HasMappedType : std::bool_constant<detail::has_mapped_type<T>::value>
{
};

template <typename T>
struct HasKeyValueAccess
    : std::bool_constant<detail::has_key_type<T>::value && detail::has_mapped_type<T>::value>
{
};

template <typename T>
struct HasContainerType : std::bool_constant<detail::has_container_type<T>::value>
{
};

template <typename T>
struct HasIterators
    : std::bool_constant<detail::has_begin_method<T>::value && detail::has_end_method<T>::value>
{
};

template <typename T>
struct HasSize : std::bool_constant<detail::has_size_method<T>::value>
{
};

template <typename T>
struct HasEmpty : std::bool_constant<detail::has_empty_method<T>::value>
{
};

template <typename T>
struct HasContiguousMemory : std::bool_constant<detail::has_data_method<T>::value &&
                                                detail::data_points_to_value_type_impl<T>::value>
{
};

template <typename T>
struct HasRandomAccess
    : std::bool_constant<
          !std::is_same<typename std::iterator_traits<typename T::iterator>::iterator_category,
                        std::bidirectional_iterator_tag>::value &&
          !std::is_same<typename std::iterator_traits<typename T::iterator>::iterator_category,
                        std::forward_iterator_tag>::value>
{
};

// ============================================================================
/// @brief  为序列化/反序列化算法提供“能否 reserve/resize/push_back/insert”
///         的编译期判断，使算法在“预分配”、“批量插入”等环节选择最优路径。
/// @details
///  设计要点：
///  1. 仅检测“是否存在对应成员函数”，不检测异常安全或复杂度，保持最小职责。
///  2. 返回 `std::true_type / false_type`，可与 `if constexpr` 直接搭配。
///  3. 对于 `HasInsert`，额外要求 `iterator` 嵌套类型，保证语义正确。
// ============================================================================

/**
 * @brief 检测类型 T 是否拥有 `reserve(size_t)` 成员函数。
 * @details
 *  主要用于 vector/string，反序列化前一次性预分配，避免多次扩容带来的拷贝开销。
 */
template <typename T, typename = void>
struct HasReserve : std::false_type
{
};
template <typename T>
struct HasReserve<
    T,
    detail::void_t<decltype(std::declval<T &>().reserve(std::declval<std::size_t>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `resize(size_t)` 成员函数。
 * @details
 *  用于在反序列化数组或字符串时，先分配目标大小，再逐元素赋值或 `memcpy`。
 */
template <typename T, typename = void>
struct HasResize : std::false_type
{
};
template <typename T>
struct HasResize<T,
                 detail::void_t<decltype(std::declval<T &>().resize(std::declval<std::size_t>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `push_back(const value_type&)` 成员函数。
 * @details
 *  线性容器（vector/list/deque）的通用追加接口，用于在反序列化时逐元素恢复。
 */
template <typename T, typename = void>
struct HasPushBack : std::false_type
{
};
template <typename T>
struct HasPushBack<
    T,
    detail::void_t<typename T::value_type,
                   decltype(std::declval<T &>().push_back(std::declval<typename T::value_type>()))>>
    : std::true_type
{
};

/**
 * @brief 检测类型 T 是否拥有 `insert(iterator, const value_type&)` 成员函数。
 * @details
 *  关联容器与顺序容器通用插入接口，用于在反序列化时把元素放入指定位置。
 */
template <typename T, typename = void>
struct HasInsert : std::false_type
{
};
template <typename T>
struct HasInsert<
    T,
    detail::void_t<typename T::value_type,
                   typename T::iterator,
                   decltype(std::declval<T &>().insert(std::declval<typename T::iterator>(),
                                                       std::declval<typename T::value_type>()))>>
    : std::true_type
{
};

/**
 * @brief 判断类型 C 是否属于“键值对”关联容器（map/unordered_map/multimap 等）。
 * @details
 *  依据：同时拥有 `key_type` 与 `mapped_type`。
 */
template <typename C>
constexpr bool MapContainer = detail::has_key_type<C>::value && detail::has_mapped_type<C>::value;

/**
 * @brief 判断类型 C 是否属于“单纯键”关联容器（set/unordered_set/multiset 等）。
 * @details
 *  依据：拥有 `key_type` 但没有 `mapped_type`。
 */
template <typename C>
constexpr bool SetContainer = detail::has_key_type<C>::value && !detail::has_mapped_type<C>::value;

/**
 * @brief 判断类型 C 是否属于“关联容器”范畴（map 或 set 家族）。
 * @details
 *  用于在算法里统一处理“按 key 排序/哈希”的容器。
 */
template <typename C>
constexpr bool AssociativeContainer = MapContainer<C> || SetContainer<C>;

/**
 * @brief 判断类型 Adapter 是否属于“容器适配器”范畴（stack/queue/priority_queue）。
 * @details
 *  依据：拥有 `container_type` 与 `push` 方法，并且至少提供 `top` 或 `front`
 *  之一，保证其“适配器”语义。
 */
template <typename Adapter>
constexpr bool AdapterContainer =
    detail::has_container_type<Adapter>::value && detail::has_push_method<Adapter>::value &&
    (detail::has_top_method<Adapter>::value || detail::has_front_method<Adapter>::value);

/**
 * @brief 判断类型 Adapter 是否为 std::stack 风格适配器。
 * @details
 *  依据：满足 AdapterContainer，仅有 `top` 而无 `front/back`。
 */
template <typename Adapter>
constexpr bool StackAdapter =
    AdapterContainer<Adapter> && detail::has_top_method<Adapter>::value &&
    !detail::has_front_method<Adapter>::value && !detail::has_back_method<Adapter>::value;

/**
 * @brief 判断类型 Adapter 是否为 std::queue 风格适配器。
 * @details
 *  依据：满足 AdapterContainer，同时拥有 `front/back` 但无 `top`。
 */
template <typename Adapter>
constexpr bool QueueAdapter =
    AdapterContainer<Adapter> && detail::has_front_method<Adapter>::value &&
        detail::has_back_method<Adapter>::value &&
    !detail::has_top_method<Adapter>::value;

/**
 * @brief 判断类型 Adapter 是否为 std::priority_queue 风格适配器。
 * @details
 *  依据：满足 AdapterContainer，仅有 `top` 而无 `front`。
 */
template <typename Adapter>
constexpr bool PriorityQueueAdapter =
    AdapterContainer<Adapter> && detail::has_top_method<Adapter>::value &&
    !detail::has_front_method<Adapter>::value && detail::top_returns_const<Adapter>::value;

/**
 * @brief 判断类型 C 是否为“连续内存顺序容器”。
 * @details
 *  典型代表：std::vector、std::array、std::string、std::span。
 *  满足条件：有 `size()/data()`，且 `data()` 返回 `value_type*`。
 *  序列化时可走“批量 memcpy” 快速路径。
 */
template <typename C>
constexpr bool ContiguousSequenceContainer = detail::has_size_method<C>::value &&
    detail::has_data_method<C>::value && detail::data_points_to_value_type_impl<C>::value;

/**
 * @brief 判断类型 C 是否为“非连续顺序容器”（list/forward_list/deque 等）。
 * @details
 *  满足条件：有 `size()/begin()/end()`，但不是关联容器也不是适配器。
 *  序列化时需逐元素迭代。
 */
template <typename C>
constexpr bool SequenceContainer =
    !std::is_reference<C>::value && !std::is_const<std::remove_reference_t<C>>::value &&
    detail::has_size_method<C>::value && detail::has_begin_method<C>::value &&
    detail::has_end_method<C>::value && !AssociativeContainer<C> && !AdapterContainer<C>;

/**
 * @brief 判断类型 C 是否为其支持的“基本容器”之一。
 * @details
 *  只要属于“连续/非连续顺序容器”、“关联容器”、“适配器”任一范畴，
 *  即认为可被本序列化库识别与处理。
 */
template <typename C>
constexpr bool BasicContainer = (ContiguousSequenceContainer<C> || SequenceContainer<C> ||
                                 AssociativeContainer<C>)&&!AdapterContainer<C>;

// ============================================================================
/// @brief  把底层线性容器还原成对应适配器，使反序列化代码能够“forward”
///         到适配器构造函数，而不必手写 push 循环。
// ============================================================================

/**
 * @brief 从底层容器重建 std::stack / std::queue / std::priority_queue。
 * @tparam Adapter 目标适配器类型，例如 `std::stack<int, std::vector<int>>`。
 * @param  underlying  已经反序列化好的底层容器（如 `std::vector<int>`）。
 * @return 重新封装好的适配器实例。
 * @details
 *  设计要点：
 *  1. 利用适配器提供的“范围构造函数”或“逐个 push”进行还原。
 *  2. 目前采用保守策略：如果存在 `push(value_type)` 则循环调用，
 *     未来可升级为“完美转发到适配器构造函数”。
 *  3. 函数签名保证 NRVO，无额外拷贝开销。
 */
template <typename Adapter>
inline Adapter
reconstruct_adapter_from_container(typename Adapter::container_type underlying)
{
    Adapter result;
    for (auto & v : underlying)
    {
        if constexpr (detail::has_push_method<Adapter>::value)
        {
            result.push(v);
        }
    }
    return result;
}

} // namespace serializer
